import { ViewportState, ZoomLevel } from './types'

/**
 * 缩放控制器
 * 管理时间线视图的缩放和滚动
 */
export class ZoomController {
  private viewportState: ViewportState
  private setViewportState: (state: ViewportState) => void
  
  // 预设缩放级别 (像素/秒)
  private static readonly ZOOM_LEVELS: ZoomLevel[] = [
    { level: 0, name: '极远', description: '1:20', scale: 2 },
    { level: 1, name: '远', description: '1:10', scale: 5 },
    { level: 2, name: '标准', description: '1:5', scale: 10 },
    { level: 3, name: '近', description: '1:2', scale: 25 },
    { level: 4, name: '极近', description: '1:1', scale: 50 }
  ]

  private currentZoomLevel: number = 2 // 默认标准级别

  constructor(
    viewportState: ViewportState,
    setViewportState: (state: ViewportState) => void
  ) {
    this.viewportState = viewportState
    this.setViewportState = setViewportState
  }

  /**
   * 放大
   */
  zoomIn(): void {
    if (this.currentZoomLevel < ZoomController.ZOOM_LEVELS.length - 1) {
      this.currentZoomLevel++
      this.applyZoom()
    }
  }

  /**
   * 缩小
   */
  zoomOut(): void {
    if (this.currentZoomLevel > 0) {
      this.currentZoomLevel--
      this.applyZoom()
    }
  }

  /**
   * 适应窗口 - 显示所有内容
   */
  zoomToFit(totalDuration: number): void {
    if (totalDuration <= 0) return

    const targetScale = Math.max(1, (this.viewportState.width - 40) / totalDuration)
    
    // 找到最接近的缩放级别
    let bestLevel = 0
    let minDiff = Math.abs(ZoomController.ZOOM_LEVELS[0].scale - targetScale)
    
    for (let i = 1; i < ZoomController.ZOOM_LEVELS.length; i++) {
      const diff = Math.abs(ZoomController.ZOOM_LEVELS[i].scale - targetScale)
      if (diff < minDiff) {
        minDiff = diff
        bestLevel = i
      }
    }

    this.currentZoomLevel = bestLevel
    this.setViewportState({
      ...this.viewportState,
      scale: ZoomController.ZOOM_LEVELS[bestLevel].scale,
      offsetX: 0 // 重置到开始位置
    })
  }

  /**
   * 滚动到指定时间
   */
  scrollToTime(time: number): void {
    const targetX = time * this.viewportState.scale
    const centerOffset = targetX - this.viewportState.width / 2
    
    this.setViewportState({
      ...this.viewportState,
      offsetX: Math.max(0, centerOffset)
    })
  }

  /**
   * 处理鼠标滚轮缩放
   */
  handleWheel(event: WheelEvent, mouseX: number): void {
    if (event.ctrlKey || event.metaKey) {
      // 阻止默认滚动行为
      event.preventDefault()
      
      // 计算鼠标位置对应的时间
      const mouseTime = (mouseX + this.viewportState.offsetX) / this.viewportState.scale
      
      // 缩放
      if (event.deltaY > 0) {
        this.zoomOut()
      } else {
        this.zoomIn()
      }
      
      // 保持鼠标位置不变
      const newMouseX = mouseTime * this.viewportState.scale
      const newOffsetX = newMouseX - mouseX
      
      this.setViewportState({
        ...this.viewportState,
        offsetX: Math.max(0, newOffsetX)
      })
    } else {
      // 水平滚动
      const scrollSpeed = 50
      const newOffsetX = this.viewportState.offsetX + event.deltaY * scrollSpeed / 100
      
      this.setViewportState({
        ...this.viewportState,
        offsetX: Math.max(0, newOffsetX)
      })
    }
  }

  /**
   * 更新视口尺寸
   */
  updateViewportSize(width: number, height: number): void {
    this.setViewportState({
      ...this.viewportState,
      width,
      height
    })
  }

  /**
   * 应用当前缩放级别
   */
  private applyZoom(): void {
    const zoomLevel = ZoomController.ZOOM_LEVELS[this.currentZoomLevel]
    
    this.setViewportState({
      ...this.viewportState,
      scale: zoomLevel.scale
    })
  }

  /**
   * 获取当前缩放信息
   */
  getCurrentZoomInfo(): {
    level: number
    name: string
    description: string
    canZoomIn: boolean
    canZoomOut: boolean
  } {
    const zoomLevel = ZoomController.ZOOM_LEVELS[this.currentZoomLevel]
    
    return {
      level: this.currentZoomLevel,
      name: zoomLevel.name,
      description: zoomLevel.description,
      canZoomIn: this.currentZoomLevel < ZoomController.ZOOM_LEVELS.length - 1,
      canZoomOut: this.currentZoomLevel > 0
    }
  }
}